package cn.edu.fudan.rule;

import cn.edu.fudan.type.Rule;
import cn.edu.fudan.type.TwoTuple;
import cn.edu.fudan.type.WaveletPerOrder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by 80494 on 2017/4/6.
 */
public class RulePruning {

    public TwoTuple<List<Rule>,Integer>RulePruning(List<Rule> originruleset, List<WaveletPerOrder> database,int k){  //k is the number og class
        List<Rule> NewRuleSet = RuleOrder(originruleset);
        List<Rule> Rpie = new ArrayList<>();
        List<WaveletPerOrder> deletedrecord= new ArrayList<>();   //用于标记将要被删除的条目
        int defaultclass=0;
        //ArrayList<Integer> deletedrecord = new ArrayList();          //用于标记将要被删除的条目的索引
        for (int j=0;j<database.size();j++) {
            for(int i=0;i<NewRuleSet.size();i++){
                if(!NewRuleSet.get(i).getPattern().getSubpatternseriesindex().contains(j)) continue;       //判断rule是否是覆盖时间序列数据点
                                                                                                            //不是的话就跳过这个rule
                if (NewRuleSet.get(i).getLabel()==database.get(j).getLabel()){  //判断类别是否相等
                    deletedrecord.add(database.get(j));
                    if(Rpie.contains(NewRuleSet.get(i))) break;   //防止重复
                    Rpie.add(NewRuleSet.get(i));
                    //deletedrecord.add(database.get(j));
                    break;
                }
            }
        }
        Rpie=RuleOrder(Rpie);


        int count=0;
        int maxcount=0;
        database.removeAll(deletedrecord);
        for(int classlabel =0 ;classlabel<k;classlabel++){
            for (WaveletPerOrder leftrecord:database){
                if(leftrecord.getLabel()==classlabel){
                    count++;
                }
            }
            if (count>maxcount){
                maxcount=count;
                defaultclass=classlabel;
            }
        }

        return new TwoTuple<List<Rule>,Integer>(Rpie,defaultclass);

    }



    private List<Rule> RuleOrder(List<Rule> O) {
        Collections.sort(O, new SortByPrecedence());
        return O;
    }
}

class SortByPrecedence implements Comparator {  //the strategy of rule order
                                                //因为是降序排列所以o1比o2大返回-1，又因为这里用多个属性所以需要嵌套
    public int compare(Object o1, Object o2) {
        Rule r1 = (Rule) o1;
        Rule r2 = (Rule) o2;
        if (r1.getConfidence() > r2.getConfidence()) {
            return -1;
        } else if (r1.getConfidence() < r2.getConfidence()) {
            return 1;
        } else {
            if (r1.getSupport() > r2.getSupport()) {
                return -1;
            } else if (r1.getSupport() > r2.getSupport()) {
                return 1;
            } else {
                if (r1.getPattern().getDseries().size() >= r2.getPattern().getDseries().size()) {
                    return -1;
                } else {
                    return 1;
                }
            }
        }
    }
}

/*class SortByConfidence implements Comparator { //sort rule by confidence decrease
    public int compare(Object o1, Object o2) {
        Rule r1 =(Rule)o1;
        Rule r2 =(Rule)o2;
        if  (r1.getConfidence() <r2.getConfidence()) return 1;
        return 0;
}}

class SortBySupport implements Comparator { //sort rule by confidence decrease
    public int compare(Object o1, Object o2) {
        Rule r1 =(Rule)o1;
        Rule r2 =(Rule)o2;
        if  (r1.getSupport() < r2.getSupport()) return 1;
        return 0;
    }}
*/